library(DESeq2)
library(pheatmap)
library(dplyr)
library(dendextend)
library(ggplot2)
#Daniela File path
design_matrix<-read.table('/Users/danielaquijano/Documents/GitHub/Transcriptomics-Final-Project-/source_files/Experimental_Design_TG (1).csv',sep=',',header=TRUE)
head(design_matrix)
#Tasnim File path
#design_matrix<-read.table('/Users/tasnimtabassum/Documents/Transcriptomics_SP22/Experimental_Design_TG.csv',sep=',',header=TRUE)

#head(design_matrix)
rownames(design_matrix)<-design_matrix$Sample
design_matrix$Sample<-NULL

design_matrix
counts_matrix<-read.table("/Users/danielaquijano/Documents/GitHub/Transcriptomics-Final-Project-/Count_Tables/allcounts.csv",sep=',',header=TRUE)
counts_matrix

Because the numbers after the dot in the ensembl IDs represent versions of genes in certain annotations, we can remove these to more easily conduct our differential gene expression analysis.

counts_matrix$V1<-gsub("\\..*","",counts_matrix$V1)

counts_matrix
# remove the "V1" from col 1
rownames(counts_matrix)<-counts_matrix$V1
counts_matrix$V1<-NULL

#head(counts_matrix)

counts_matrix<-counts_matrix[,order(colnames(counts_matrix))]
counts_matrix
design_matrix<-design_matrix[order(rownames(design_matrix)),]

design_matrix
NA

design_matrix$Age = factor(design_matrix$Age)

design_matrix$Age
 [1] eight  eight  two    two    eight  eight  two    two    two    eight  eight  eight 
[13] two    two    eight  eight  two    two    two    two    eight  eight  eight  eight 
[25] two    two    six    six    six    six    twelve twelve twelve twelve twelve twelve
[37] twelve twelve six    six    twelve twelve six    six    twelve twelve six    six   
[49] six    six    twelve twelve six    six    twelve twelve six    six    twelve twelve
[61] twelve twelve twelve twelve six    six    six    six    two    two    eight  eight 
Levels: eight six twelve two
dds <- DESeqDataSetFromMatrix(countData = counts_matrix,
                              colData = design_matrix,
                              design = ~ Age+Genotype)
Warning in DESeqDataSet(se, design = design, ignoreRank) :
  some variables in design formula are characters, converting to factors
dds
class: DESeqDataSet 
dim: 46075 72 
metadata(1): version
assays(1): counts
rownames(46075): ENSMUSG00000000001 ENSMUSG00000000003 ... N_noFeature N_unmapped
rowData names(0):
colnames(72): SRR8512301 SRR8512302 ... SRR8512439 SRR8512440
colData names(3): Model Genotype Age
keep <- rowSums(counts(dds)) >= 10
dds <- dds[keep,]
dds <- DESeq(dds)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
-- replacing outliers and refitting for 13457 genes
-- DESeq argument 'minReplicatesForReplace' = 7 
-- original counts are preserved in counts(dds)
estimating dispersions
fitting model and testing
normalizedcounts.matrix <- counts(dds,normalized=T)
vst_dds <- vst(dds)

dists <- dist(t(assay(vst_dds)))
head(vst_dds)
class: DESeqTransform 
dim: 6 72 
metadata(1): version
assays(1): ''
rownames(6): ENSMUSG00000000001 ENSMUSG00000000028 ... ENSMUSG00000000049
  ENSMUSG00000000056
rowData names(43): baseMean baseVar ... replace dispFit
colnames(72): SRR8512301 SRR8512302 ... SRR8512439 SRR8512440
colData names(5): Model Genotype Age sizeFactor replaceable


PCA_Genotype<-plotPCA(vst_dds,intgroup=c("Age"))+labs(title = "PCA of mice of different ages", color = "Group")+coord_fixed(ratio=3)
Coordinate system already present. Adding new coordinate system, which will replace the existing one.
PCA_Genotype

resultsNames(dds)
[1] "Intercept"               "Age_six_vs_eight"        "Age_twelve_vs_eight"    
[4] "Age_two_vs_eight"        "Genotype_rtg4510_vs_J20" "Genotype_WT_vs_J20"     
[7] "Genotype_WT_TG_vs_J20"  
dds$Age
 [1] eight  eight  two    two    eight  eight  two    two    two    eight  eight  eight 
[13] two    two    eight  eight  two    two    two    two    eight  eight  eight  eight 
[25] two    two    six    six    six    six    twelve twelve twelve twelve twelve twelve
[37] twelve twelve six    six    twelve twelve six    six    twelve twelve six    six   
[49] six    six    twelve twelve six    six    twelve twelve six    six    twelve twelve
[61] twelve twelve twelve twelve six    six    six    six    two    two    eight  eight 
Levels: eight six twelve two
#Compare 2 vs 8
res_1 <- results(dds, contrast = c("Age", "two", "eight"))
res1_ordered <- res_1[order(res_1$padj),] 
head(res1_ordered)
log2 fold change (MLE): Age two vs eight 
Wald test p-value: Age two vs eight 
DataFrame with 6 rows and 6 columns
                    baseMean log2FoldChange     lfcSE      stat      pvalue        padj
                   <numeric>      <numeric> <numeric> <numeric>   <numeric>   <numeric>
ENSMUSG00000024501 1037.7531       0.574615 0.0533228  10.77617 4.46085e-27 8.33420e-23
ENSMUSG00000030577   10.9689      -4.378147 0.4088867 -10.70748 9.38804e-27 8.76984e-23
ENSMUSG00000026303   45.6887      -1.152385 0.1270487  -9.07042 1.18562e-19 7.38363e-16
ENSMUSG00000030124  162.9878      -1.526436 0.1688798  -9.03859 1.58703e-19 7.41263e-16
ENSMUSG00000046805  863.4728      -1.317521 0.1476032  -8.92610 4.41290e-19 1.64892e-15
ENSMUSG00000029816   69.7214      -1.694819 0.1920511  -8.82483 1.09623e-18 3.41349e-15
plotDispEsts(dds)

Install Mouse annotation library:

library(biomaRt) #For conversion of transcript IDs to gene ID
library(annotables) #to retrieve grcm38 annotation for mouse genome
library(org.Mm.eg.db) #Mouse genome annotation
library(DOSE)
library(pathview)
library(clusterProfiler)
library(AnnotationHub) 
library(ensembldb)
library(tidyverse)
library(ggnewscale)
# mouse genome load
grcm38

# check that ensgene in our df is prsent in the mouse genome df

idx <- grcm38$ensgene %in% rownames(res1_ordered)
# head(idx)

# df with all the ids that are in our df from the mouse genome df
ids <- grcm38[idx, ]

# head(ids)

# remove duplicates

non_duplicates <- which(duplicated(ids$ensgene) == FALSE)
ids <- ids[non_duplicates, ]

#nrow(res1_ordered)

#rownames(res1_ordered)

# entrezID contains only the IDs that are also in our df

ensgeneID= grcm38[grcm38$ensgene %in% rownames(res1_ordered), ]

# entrezID contains only the IDs that are also in our df

entrezID= grcm38[grcm38$ensgene %in% rownames(res1_ordered), ]
# check nrow ensgeneID
head(ensgeneID)

# create a vector of only the ensgeneIDs
ensgene_ID_vector = c(ensgeneID[[1]])

head(ensgene_ID_vector)
[1] "ENSMUSG00000000001" "ENSMUSG00000000028" "ENSMUSG00000000031" "ENSMUSG00000000037"
[5] "ENSMUSG00000000049" "ENSMUSG00000000056"
# create a vector of only the entrezIDs
entrez_ID_vector = c(entrezID[[2]])

# create a vector of only the gene symbols
gene_symbols = subset(grcm38$symbol, grcm38$ensgene %in% rownames(res1_ordered))

# create new df that contains only the ensgeneIDs, lfc and padj
res2= data.frame(log2foldchange= subset(res1_ordered$log2FoldChange, grcm38$ensgene %in% rownames(res1_ordered)))
padj = subset(res1_ordered$padj, grcm38$ensgene %in% rownames(res1_ordered))
res2 = cbind(padj, res2)
res2 = cbind(ensgene_ID_vector, res2)
res2 = cbind(entrez_ID_vector, res2)
res2 = cbind(gene_symbols, res2)


# omit all "na" values
res2 = na.omit(res2)

res2 <- res2[order(res2$padj),] 
head(res2)
## Significant genes is a vector of fold changes where the names are ENTREZ gene IDs. The background set is a vector of all the genes represented on the platform.

# bg entrez contains all the ensgene

allOEgenes = as.character(res2$ensgene_ID_vector)

# sig res entrez contains all the entrezIDs that have padj <0.05
head(res2)

sigOE <- subset(res2, padj< 0.05)

head(sigOE)
# vector of only lfc values
sigOE_genes = as.character(sigOE$ensgene_ID_vector)

head(sigOE_genes)
[1] "ENSMUSG00000000001" "ENSMUSG00000000028" "ENSMUSG00000000037" "ENSMUSG00000000049"
[5] "ENSMUSG00000000056" "ENSMUSG00000000058"
## Run GO enrichment analysis 
ego <- enrichGO(gene = sigOE_genes, 
                universe = allOEgenes,
                keyType = "ENSEMBL",
                OrgDb = org.Mm.eg.db, 
                ont = "ALL", 
                pAdjustMethod = "BH", 
                qvalueCutoff = 0.05, 
                readable = TRUE,
                pool  = TRUE)

                
## Output results from GO analysis to a table
cluster_summary <- data.frame(ego)

#gene_ratio = cluster_summary[order(cluster_summary$pvalue, decreasing = FALSE), ]
#head(gene_ratio)
ego
## Dotplot 
dotplot(ego, showCategory=35)+theme(text = element_text(size = 1)) +scale_y_discrete(labels=function(x) str_wrap(x, width=40))+ggtitle('Enriched genes when comparing rtg4510 mice at 2 and 8 months')+ theme(plot.title = element_text(size=16))
Scale for 'y' is already present. Adding another scale for 'y', which will replace the
existing scale.

#barplot(ego, showCategory = 20)
options(ggrepel.max.overlaps = Inf)

## To color genes by log2 fold changes, we need to extract the log2 fold changes from our results table creating a named vector
OE_foldchanges <- sigOE$log2foldchange

names(OE_foldchanges) <- sigOE$gene_symbols

## Cnetplot details the genes associated with one or more terms - by default gives the top 1 significant term (by padj)

cnetplot(ego, 
         categorySize="pvalue", 
         showCategory = 5,
         colorEdge = TRUE,
         circular = FALSE,
         node_label = "all",
         cex_category = 1.5,
         cex_gene = 0.75,
         cex_label_category = 1.5,
         cex_label_gene = 0.75,
         shadowtext = "all")+ggtitle('Enriched Genes when comparing J20 mice at 6 and 12 months ')

NA
NA
NA
NA
library(enrichplot)
ego2 = pairwise_termsim(ego)
emapplot(ego2, showCategory = 20, colorEdge = TRUE)+ggtitle('Enriched Genes when comparing J20 mice at 6 and 12 months of age')

# Set-up

#BiocManager::install("SPIA")
library(SPIA)

## Significant genes is a vector of fold changes where the names are ENTREZ gene IDs. The background set is a vector of all the genes represented on the platform.

# bg entrez contains all the entrezIDs 

background_entrez <- res2$entrez_ID_vector

# sig res entrez contains all the entrezIDs that have padj <0.05

sig_res_entrez <- res2[which(res2$padj < 0.05), ]

# vector of only lfc values
sig_entrez <- sig_res_entrez$log2foldchange

head(sig_entrez)


# adding entrezIDs as names for the sig entrez
names(sig_entrez) <- sig_res_entrez$entrez_ID_vector

head(sig_entrez)

# remove dups
dups<-unique(names(sig_entrez[which(duplicated(names(sig_entrez)))]))
sig_entrez<-sig_entrez[!(names(sig_entrez) %in% dups)]


#de= as.vector(sig_entrez)

#de = sort(de, decreasing = FALSE)

# this step takes time

spia_result <- spia(de=sig_entrez, all=background_entrez, organism="mmu", plots=FALSE)
write.csv(spia_result, file = "spia_result_J20_age.csv")

# view one record at a time

subset(spia_result, ID == "04727")

head(res1_ordered)
norm_counts_top_40 = normalizedcounts.matrix[row.names(head(res1_ordered, 40)), ]
nrow(norm_counts_top_40)
head(design_matrix)

annotation_columns<-design_matrix

row.names(annotation_columns) <- colnames(norm_counts_top_40)

library(pheatmap)

tiff("Heatmap_J20_age.tiff", width = 7, height = 5, units = 'in', res = 300)
pheatmap(norm_counts_top_40, color=colorRampPalette(c("white", "orchid3", "purple4"))(30), scale="row", cluster_cols = T, show_rownames = T,fontsize = 7,fontsize_row = 4, fontsize_col = 4,labels_row = rownames(dists),annotation_col =annotation_columns,main='Differentially Expressed Genes in J20 mice at 6 and 12 months old' )
dev.off()
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CgpsaWJyYXJ5KERFU2VxMikKbGlicmFyeShwaGVhdG1hcCkKbGlicmFyeShkcGx5cikKbGlicmFyeShkZW5kZXh0ZW5kKQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKYGBge3J9CiNEYW5pZWxhIEZpbGUgcGF0aApkZXNpZ25fbWF0cml4PC1yZWFkLnRhYmxlKCcvVXNlcnMvZGFuaWVsYXF1aWphbm8vRG9jdW1lbnRzL0dpdEh1Yi9UcmFuc2NyaXB0b21pY3MtRmluYWwtUHJvamVjdC0vc291cmNlX2ZpbGVzL0V4cGVyaW1lbnRhbF9EZXNpZ25fVEcgKDEpLmNzdicsc2VwPScsJyxoZWFkZXI9VFJVRSkKaGVhZChkZXNpZ25fbWF0cml4KQpgYGAKCmBgYHtyfQojVGFzbmltIEZpbGUgcGF0aAojZGVzaWduX21hdHJpeDwtcmVhZC50YWJsZSgnL1VzZXJzL3Rhc25pbXRhYmFzc3VtL0RvY3VtZW50cy9UcmFuc2NyaXB0b21pY3NfU1AyMi9FeHBlcmltZW50YWxfRGVzaWduX1RHLmNzdicsc2VwPScsJyxoZWFkZXI9VFJVRSkKCiNoZWFkKGRlc2lnbl9tYXRyaXgpCmBgYAoKYGBge3J9CnJvd25hbWVzKGRlc2lnbl9tYXRyaXgpPC1kZXNpZ25fbWF0cml4JFNhbXBsZQpkZXNpZ25fbWF0cml4JFNhbXBsZTwtTlVMTAoKZGVzaWduX21hdHJpeApgYGAKCmBgYHtyfQpjb3VudHNfbWF0cml4PC1yZWFkLnRhYmxlKCIvVXNlcnMvZGFuaWVsYXF1aWphbm8vRG9jdW1lbnRzL0dpdEh1Yi9UcmFuc2NyaXB0b21pY3MtRmluYWwtUHJvamVjdC0vQ291bnRfVGFibGVzL2FsbGNvdW50cy5jc3YiLHNlcD0nLCcsaGVhZGVyPVRSVUUpCmNvdW50c19tYXRyaXgKYGBgCgoKCkJlY2F1c2UgdGhlIG51bWJlcnMgYWZ0ZXIgdGhlIGRvdCBpbiB0aGUgZW5zZW1ibCBJRHMgcmVwcmVzZW50IHZlcnNpb25zIG9mIGdlbmVzIGluIGNlcnRhaW4gYW5ub3RhdGlvbnMsIHdlIGNhbiByZW1vdmUgdGhlc2UgdG8gbW9yZSBlYXNpbHkgY29uZHVjdCBvdXIgZGlmZmVyZW50aWFsIGdlbmUgZXhwcmVzc2lvbiBhbmFseXNpcy4gCmBgYHtyfQpjb3VudHNfbWF0cml4JFYxPC1nc3ViKCJcXC4uKiIsIiIsY291bnRzX21hdHJpeCRWMSkKCmNvdW50c19tYXRyaXgKYGBgCgpgYGB7cn0KIyByZW1vdmUgdGhlICJWMSIgZnJvbSBjb2wgMQpyb3duYW1lcyhjb3VudHNfbWF0cml4KTwtY291bnRzX21hdHJpeCRWMQpjb3VudHNfbWF0cml4JFYxPC1OVUxMCgojaGVhZChjb3VudHNfbWF0cml4KQoKY291bnRzX21hdHJpeDwtY291bnRzX21hdHJpeFssb3JkZXIoY29sbmFtZXMoY291bnRzX21hdHJpeCkpXQpjb3VudHNfbWF0cml4CmBgYAoKYGBge3J9CmRlc2lnbl9tYXRyaXg8LWRlc2lnbl9tYXRyaXhbb3JkZXIocm93bmFtZXMoZGVzaWduX21hdHJpeCkpLF0KCmRlc2lnbl9tYXRyaXgKCmBgYAoKYGBge3J9CgpkZXNpZ25fbWF0cml4JEFnZSA9IGZhY3RvcihkZXNpZ25fbWF0cml4JEFnZSkKCmRlc2lnbl9tYXRyaXgkQWdlCgoKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhID0gY291bnRzX21hdHJpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IGRlc2lnbl9tYXRyaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IH4gQWdlK0dlbm90eXBlKQpkZHMKCmtlZXAgPC0gcm93U3Vtcyhjb3VudHMoZGRzKSkgPj0gMTAKZGRzIDwtIGRkc1trZWVwLF0KYGBgCgoKYGBge3J9CmRkcyA8LSBERVNlcShkZHMpCmBgYAoKYGBge3J9Cm5vcm1hbGl6ZWRjb3VudHMubWF0cml4IDwtIGNvdW50cyhkZHMsbm9ybWFsaXplZD1UKQoKYGBgCgoKYGBge3J9CnZzdF9kZHMgPC0gdnN0KGRkcykKCmRpc3RzIDwtIGRpc3QodChhc3NheSh2c3RfZGRzKSkpCmhlYWQodnN0X2RkcykKYGBgCgoKYGBge3J9CgoKUENBX0dlbm90eXBlPC1wbG90UENBKHZzdF9kZHMsaW50Z3JvdXA9YygiQWdlIikpK2xhYnModGl0bGUgPSAiUENBIG9mIG1pY2Ugb2YgZGlmZmVyZW50IGFnZXMiLCBjb2xvciA9ICJHcm91cCIpK2Nvb3JkX2ZpeGVkKHJhdGlvPTMpCgpQQ0FfR2Vub3R5cGUKYGBgCgpgYGB7cn0KcmVzdWx0c05hbWVzKGRkcykKYGBgCmBgYHtyfQpkZHMkQWdlCmBgYAoKYGBge3J9CiNDb21wYXJlIDIgdnMgOApyZXNfMSA8LSByZXN1bHRzKGRkcywgY29udHJhc3QgPSBjKCJBZ2UiLCAidHdvIiwgImVpZ2h0IikpCnJlczFfb3JkZXJlZCA8LSByZXNfMVtvcmRlcihyZXNfMSRwYWRqKSxdIApoZWFkKHJlczFfb3JkZXJlZCkKYGBgCmBgYHtyfQpwbG90RGlzcEVzdHMoZGRzKQoKYGBgCgpJbnN0YWxsIE1vdXNlIGFubm90YXRpb24gbGlicmFyeToKCmBgYHtyfQpsaWJyYXJ5KGJpb21hUnQpICNGb3IgY29udmVyc2lvbiBvZiB0cmFuc2NyaXB0IElEcyB0byBnZW5lIElECmxpYnJhcnkoYW5ub3RhYmxlcykgI3RvIHJldHJpZXZlIGdyY20zOCBhbm5vdGF0aW9uIGZvciBtb3VzZSBnZW5vbWUKbGlicmFyeShvcmcuTW0uZWcuZGIpICNNb3VzZSBnZW5vbWUgYW5ub3RhdGlvbgpsaWJyYXJ5KERPU0UpCmxpYnJhcnkocGF0aHZpZXcpCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KEFubm90YXRpb25IdWIpIApsaWJyYXJ5KGVuc2VtYmxkYikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2duZXdzY2FsZSkKYGBgCgpgYGB7cn0KIyBtb3VzZSBnZW5vbWUgbG9hZApncmNtMzgKCiMgY2hlY2sgdGhhdCBlbnNnZW5lIGluIG91ciBkZiBpcyBwcnNlbnQgaW4gdGhlIG1vdXNlIGdlbm9tZSBkZgoKaWR4IDwtIGdyY20zOCRlbnNnZW5lICVpbiUgcm93bmFtZXMocmVzMV9vcmRlcmVkKQojIGhlYWQoaWR4KQoKIyBkZiB3aXRoIGFsbCB0aGUgaWRzIHRoYXQgYXJlIGluIG91ciBkZiBmcm9tIHRoZSBtb3VzZSBnZW5vbWUgZGYKaWRzIDwtIGdyY20zOFtpZHgsIF0KCiMgaGVhZChpZHMpCgojIHJlbW92ZSBkdXBsaWNhdGVzCgpub25fZHVwbGljYXRlcyA8LSB3aGljaChkdXBsaWNhdGVkKGlkcyRlbnNnZW5lKSA9PSBGQUxTRSkKaWRzIDwtIGlkc1tub25fZHVwbGljYXRlcywgXQpgYGAKCmBgYHtyfQoKI25yb3cocmVzMV9vcmRlcmVkKQoKI3Jvd25hbWVzKHJlczFfb3JkZXJlZCkKCiMgZW50cmV6SUQgY29udGFpbnMgb25seSB0aGUgSURzIHRoYXQgYXJlIGFsc28gaW4gb3VyIGRmCgplbnNnZW5lSUQ9IGdyY20zOFtncmNtMzgkZW5zZ2VuZSAlaW4lIHJvd25hbWVzKHJlczFfb3JkZXJlZCksIF0KCiMgZW50cmV6SUQgY29udGFpbnMgb25seSB0aGUgSURzIHRoYXQgYXJlIGFsc28gaW4gb3VyIGRmCgplbnRyZXpJRD0gZ3JjbTM4W2dyY20zOCRlbnNnZW5lICVpbiUgcm93bmFtZXMocmVzMV9vcmRlcmVkKSwgXQojIGNoZWNrIG5yb3cgZW5zZ2VuZUlECmhlYWQoZW5zZ2VuZUlEKQoKIyBjcmVhdGUgYSB2ZWN0b3Igb2Ygb25seSB0aGUgZW5zZ2VuZUlEcwplbnNnZW5lX0lEX3ZlY3RvciA9IGMoZW5zZ2VuZUlEW1sxXV0pCgpoZWFkKGVuc2dlbmVfSURfdmVjdG9yKQoKCiMgY3JlYXRlIGEgdmVjdG9yIG9mIG9ubHkgdGhlIGVudHJleklEcwplbnRyZXpfSURfdmVjdG9yID0gYyhlbnRyZXpJRFtbMl1dKQoKIyBjcmVhdGUgYSB2ZWN0b3Igb2Ygb25seSB0aGUgZ2VuZSBzeW1ib2xzCmdlbmVfc3ltYm9scyA9IHN1YnNldChncmNtMzgkc3ltYm9sLCBncmNtMzgkZW5zZ2VuZSAlaW4lIHJvd25hbWVzKHJlczFfb3JkZXJlZCkpCgojIGNyZWF0ZSBuZXcgZGYgdGhhdCBjb250YWlucyBvbmx5IHRoZSBlbnNnZW5lSURzLCBsZmMgYW5kIHBhZGoKcmVzMj0gZGF0YS5mcmFtZShsb2cyZm9sZGNoYW5nZT0gc3Vic2V0KHJlczFfb3JkZXJlZCRsb2cyRm9sZENoYW5nZSwgZ3JjbTM4JGVuc2dlbmUgJWluJSByb3duYW1lcyhyZXMxX29yZGVyZWQpKSkKcGFkaiA9IHN1YnNldChyZXMxX29yZGVyZWQkcGFkaiwgZ3JjbTM4JGVuc2dlbmUgJWluJSByb3duYW1lcyhyZXMxX29yZGVyZWQpKQpyZXMyID0gY2JpbmQocGFkaiwgcmVzMikKcmVzMiA9IGNiaW5kKGVuc2dlbmVfSURfdmVjdG9yLCByZXMyKQpyZXMyID0gY2JpbmQoZW50cmV6X0lEX3ZlY3RvciwgcmVzMikKcmVzMiA9IGNiaW5kKGdlbmVfc3ltYm9scywgcmVzMikKCgojIG9taXQgYWxsICJuYSIgdmFsdWVzCnJlczIgPSBuYS5vbWl0KHJlczIpCgpyZXMyIDwtIHJlczJbb3JkZXIocmVzMiRwYWRqKSxdIApoZWFkKHJlczIpCmBgYAoKYGBge3J9CiMjIFNpZ25pZmljYW50IGdlbmVzIGlzIGEgdmVjdG9yIG9mIGZvbGQgY2hhbmdlcyB3aGVyZSB0aGUgbmFtZXMgYXJlIEVOVFJFWiBnZW5lIElEcy4gVGhlIGJhY2tncm91bmQgc2V0IGlzIGEgdmVjdG9yIG9mIGFsbCB0aGUgZ2VuZXMgcmVwcmVzZW50ZWQgb24gdGhlIHBsYXRmb3JtLgoKIyBiZyBlbnRyZXogY29udGFpbnMgYWxsIHRoZSBlbnNnZW5lCgphbGxPRWdlbmVzID0gYXMuY2hhcmFjdGVyKHJlczIkZW5zZ2VuZV9JRF92ZWN0b3IpCgojIHNpZyByZXMgZW50cmV6IGNvbnRhaW5zIGFsbCB0aGUgZW50cmV6SURzIHRoYXQgaGF2ZSBwYWRqIDwwLjA1CmhlYWQocmVzMikKCnNpZ09FIDwtIHN1YnNldChyZXMyLCBwYWRqPCAwLjA1KQoKaGVhZChzaWdPRSkKIyB2ZWN0b3Igb2Ygb25seSBsZmMgdmFsdWVzCnNpZ09FX2dlbmVzID0gYXMuY2hhcmFjdGVyKHNpZ09FJGVuc2dlbmVfSURfdmVjdG9yKQoKaGVhZChzaWdPRV9nZW5lcykKCmBgYAoKCmBgYHtyfQojIyBSdW4gR08gZW5yaWNobWVudCBhbmFseXNpcyAKZWdvIDwtIGVucmljaEdPKGdlbmUgPSBzaWdPRV9nZW5lcywgCiAgICAgICAgICAgICAgICB1bml2ZXJzZSA9IGFsbE9FZ2VuZXMsCiAgICAgICAgICAgICAgICBrZXlUeXBlID0gIkVOU0VNQkwiLAogICAgICAgICAgICAgICAgT3JnRGIgPSBvcmcuTW0uZWcuZGIsIAogICAgICAgICAgICAgICAgb250ID0gIkFMTCIsIAogICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIAogICAgICAgICAgICAgICAgcXZhbHVlQ3V0b2ZmID0gMC4wNSwgCiAgICAgICAgICAgICAgICByZWFkYWJsZSA9IFRSVUUsCiAgICAgICAgICAgICAgICBwb29sICA9IFRSVUUpCgogICAgICAgICAgICAgICAgCiMjIE91dHB1dCByZXN1bHRzIGZyb20gR08gYW5hbHlzaXMgdG8gYSB0YWJsZQpjbHVzdGVyX3N1bW1hcnkgPC0gZGF0YS5mcmFtZShlZ28pCgojZ2VuZV9yYXRpbyA9IGNsdXN0ZXJfc3VtbWFyeVtvcmRlcihjbHVzdGVyX3N1bW1hcnkkcHZhbHVlLCBkZWNyZWFzaW5nID0gRkFMU0UpLCBdCiNoZWFkKGdlbmVfcmF0aW8pCgoKYGBgCmBgYHtyfQplZ28KYGBgCgoKYGBge3IgZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MjB9CiMjIERvdHBsb3QgCmRvdHBsb3QoZWdvLCBzaG93Q2F0ZWdvcnk9MzUpK3RoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEpKSArc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHM9ZnVuY3Rpb24oeCkgc3RyX3dyYXAoeCwgd2lkdGg9NDApKStnZ3RpdGxlKCdFbnJpY2hlZCBnZW5lcyB3aGVuIGNvbXBhcmluZyBydGc0NTEwIG1pY2UgYXQgMiBhbmQgOCBtb250aHMnKSsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE2KSkKCiNiYXJwbG90KGVnbywgc2hvd0NhdGVnb3J5ID0gMjApCmBgYAoKCgoKCmBgYHtyIGZpZy53aWR0aD0yMCxmaWcuaGVpZ2h0PTIwfQpvcHRpb25zKGdncmVwZWwubWF4Lm92ZXJsYXBzID0gSW5mKQoKIyMgVG8gY29sb3IgZ2VuZXMgYnkgbG9nMiBmb2xkIGNoYW5nZXMsIHdlIG5lZWQgdG8gZXh0cmFjdCB0aGUgbG9nMiBmb2xkIGNoYW5nZXMgZnJvbSBvdXIgcmVzdWx0cyB0YWJsZSBjcmVhdGluZyBhIG5hbWVkIHZlY3RvcgpPRV9mb2xkY2hhbmdlcyA8LSBzaWdPRSRsb2cyZm9sZGNoYW5nZQoKbmFtZXMoT0VfZm9sZGNoYW5nZXMpIDwtIHNpZ09FJGdlbmVfc3ltYm9scwoKIyMgQ25ldHBsb3QgZGV0YWlscyB0aGUgZ2VuZXMgYXNzb2NpYXRlZCB3aXRoIG9uZSBvciBtb3JlIHRlcm1zIC0gYnkgZGVmYXVsdCBnaXZlcyB0aGUgdG9wIDEgc2lnbmlmaWNhbnQgdGVybSAoYnkgcGFkaikKCmNuZXRwbG90KGVnbywgCiAgICAgICAgIGNhdGVnb3J5U2l6ZT0icHZhbHVlIiwgCiAgICAgICAgIHNob3dDYXRlZ29yeSA9IDUsCiAgICAgICAgIGNvbG9yRWRnZSA9IFRSVUUsCiAgICAgICAgIGNpcmN1bGFyID0gRkFMU0UsCiAgICAgICAgIG5vZGVfbGFiZWwgPSAiYWxsIiwKICAgICAgICAgY2V4X2NhdGVnb3J5ID0gMS41LAogICAgICAgICBjZXhfZ2VuZSA9IDAuNzUsCiAgICAgICAgIGNleF9sYWJlbF9jYXRlZ29yeSA9IDEuNSwKICAgICAgICAgY2V4X2xhYmVsX2dlbmUgPSAwLjc1LAogICAgICAgICBzaGFkb3d0ZXh0ID0gImFsbCIpK2dndGl0bGUoJ0VucmljaGVkIEdlbmVzIHdoZW4gY29tcGFyaW5nIEoyMCBtaWNlIGF0IDYgYW5kIDEyIG1vbnRocyAnKQogICAgICAgICAKCgoKYGBgCgoKYGBge3IgZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MjB9CmxpYnJhcnkoZW5yaWNocGxvdCkKZWdvMiA9IHBhaXJ3aXNlX3Rlcm1zaW0oZWdvKQplbWFwcGxvdChlZ28yLCBzaG93Q2F0ZWdvcnkgPSAyMCwgY29sb3JFZGdlID0gVFJVRSkrZ2d0aXRsZSgnRW5yaWNoZWQgR2VuZXMgd2hlbiBjb21wYXJpbmcgSjIwIG1pY2UgYXQgNiBhbmQgMTIgbW9udGhzIG9mIGFnZScpCgpgYGAKCgpgYGB7cn0KCiMgU2V0LXVwCgojQmlvY01hbmFnZXI6Omluc3RhbGwoIlNQSUEiKQpsaWJyYXJ5KFNQSUEpCgojIyBTaWduaWZpY2FudCBnZW5lcyBpcyBhIHZlY3RvciBvZiBmb2xkIGNoYW5nZXMgd2hlcmUgdGhlIG5hbWVzIGFyZSBFTlRSRVogZ2VuZSBJRHMuIFRoZSBiYWNrZ3JvdW5kIHNldCBpcyBhIHZlY3RvciBvZiBhbGwgdGhlIGdlbmVzIHJlcHJlc2VudGVkIG9uIHRoZSBwbGF0Zm9ybS4KCiMgYmcgZW50cmV6IGNvbnRhaW5zIGFsbCB0aGUgZW50cmV6SURzIAoKYmFja2dyb3VuZF9lbnRyZXogPC0gcmVzMiRlbnRyZXpfSURfdmVjdG9yCgojIHNpZyByZXMgZW50cmV6IGNvbnRhaW5zIGFsbCB0aGUgZW50cmV6SURzIHRoYXQgaGF2ZSBwYWRqIDwwLjA1CgpzaWdfcmVzX2VudHJleiA8LSByZXMyW3doaWNoKHJlczIkcGFkaiA8IDAuMDUpLCBdCgojIHZlY3RvciBvZiBvbmx5IGxmYyB2YWx1ZXMKc2lnX2VudHJleiA8LSBzaWdfcmVzX2VudHJleiRsb2cyZm9sZGNoYW5nZQoKaGVhZChzaWdfZW50cmV6KQoKCiMgYWRkaW5nIGVudHJleklEcyBhcyBuYW1lcyBmb3IgdGhlIHNpZyBlbnRyZXoKbmFtZXMoc2lnX2VudHJleikgPC0gc2lnX3Jlc19lbnRyZXokZW50cmV6X0lEX3ZlY3RvcgoKaGVhZChzaWdfZW50cmV6KQoKIyByZW1vdmUgZHVwcwpkdXBzPC11bmlxdWUobmFtZXMoc2lnX2VudHJlelt3aGljaChkdXBsaWNhdGVkKG5hbWVzKHNpZ19lbnRyZXopKSldKSkKc2lnX2VudHJlejwtc2lnX2VudHJlelshKG5hbWVzKHNpZ19lbnRyZXopICVpbiUgZHVwcyldCgoKYGBgCgoKCmBgYHtyfQoKCiNkZT0gYXMudmVjdG9yKHNpZ19lbnRyZXopCgojZGUgPSBzb3J0KGRlLCBkZWNyZWFzaW5nID0gRkFMU0UpCgojIHRoaXMgc3RlcCB0YWtlcyB0aW1lCgpzcGlhX3Jlc3VsdCA8LSBzcGlhKGRlPXNpZ19lbnRyZXosIGFsbD1iYWNrZ3JvdW5kX2VudHJleiwgb3JnYW5pc209Im1tdSIsIHBsb3RzPUZBTFNFKQoKYGBgCgpgYGB7cn0Kd3JpdGUuY3N2KHNwaWFfcmVzdWx0LCBmaWxlID0gInNwaWFfcmVzdWx0X0oyMF9hZ2UuY3N2IikKCmBgYAoKCgpgYGB7cn0KCiMgdmlldyBvbmUgcmVjb3JkIGF0IGEgdGltZQoKc3Vic2V0KHNwaWFfcmVzdWx0LCBJRCA9PSAiMDQ3MjciKQoKYGBgCgpgYGB7cn0KCmhlYWQocmVzMV9vcmRlcmVkKQpub3JtX2NvdW50c190b3BfNDAgPSBub3JtYWxpemVkY291bnRzLm1hdHJpeFtyb3cubmFtZXMoaGVhZChyZXMxX29yZGVyZWQsIDQwKSksIF0KYGBgCgpgYGB7cn0KbnJvdyhub3JtX2NvdW50c190b3BfNDApCmBgYAoKYGBge3J9CmhlYWQoZGVzaWduX21hdHJpeCkKCmFubm90YXRpb25fY29sdW1uczwtZGVzaWduX21hdHJpeAoKcm93Lm5hbWVzKGFubm90YXRpb25fY29sdW1ucykgPC0gY29sbmFtZXMobm9ybV9jb3VudHNfdG9wXzQwKQoKbGlicmFyeShwaGVhdG1hcCkKYGBgCgpgYGB7cn0KCnRpZmYoIkhlYXRtYXBfSjIwX2FnZS50aWZmIiwgd2lkdGggPSA3LCBoZWlnaHQgPSA1LCB1bml0cyA9ICdpbicsIHJlcyA9IDMwMCkKcGhlYXRtYXAobm9ybV9jb3VudHNfdG9wXzQwLCBjb2xvcj1jb2xvclJhbXBQYWxldHRlKGMoIndoaXRlIiwgIm9yY2hpZDMiLCAicHVycGxlNCIpKSgzMCksIHNjYWxlPSJyb3ciLCBjbHVzdGVyX2NvbHMgPSBULCBzaG93X3Jvd25hbWVzID0gVCxmb250c2l6ZSA9IDcsZm9udHNpemVfcm93ID0gNCwgZm9udHNpemVfY29sID0gNCxsYWJlbHNfcm93ID0gcm93bmFtZXMoZGlzdHMpLGFubm90YXRpb25fY29sID1hbm5vdGF0aW9uX2NvbHVtbnMsbWFpbj0nRGlmZmVyZW50aWFsbHkgRXhwcmVzc2VkIEdlbmVzIGluIEoyMCBtaWNlIGF0IDYgYW5kIDEyIG1vbnRocyBvbGQnICkKZGV2Lm9mZigpCmBgYAoK